package com.sophic_tech.hkb.service.auth.Impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.sophic_tech.hkb.entity.AccountModel;
import com.sophic_tech.hkb.entity.AuthModel;
import com.sophic_tech.hkb.entity.LoginResultModel;
import com.sophic_tech.hkb.entity.Result;
import com.sophic_tech.hkb.mapper.AuthMapper;
import com.sophic_tech.hkb.service.auth.LoginService;
import com.sophic_tech.hkb.service.auth.RegisterService;
import com.sophic_tech.hkb.utils.JWTUtils;
import com.sophic_tech.hkb.utils.StringUtils;
import com.sophic_tech.hkb.utils.StringUtilsKt;
import jakarta.annotation.Resource;
import lombok.extern.slf4j.Slf4j;
import org.springframework.dao.DuplicateKeyException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.stereotype.Service;

@Slf4j
@Service
public class AuthService implements LoginService, RegisterService {
    @Resource
    private AuthMapper authMapper;
    @Resource
    private BCryptPasswordEncoder bCryptPasswordEncoder;

    @Override
    public Result loginService(AuthModel model) {
        log.info("开始处理登录请求，账号：{}, 密码：{}", model.getAccount(), model.getPassword().isBlank() ? "空" : "******");
        String account = model.getAccount();
        LambdaQueryWrapper<AccountModel> wrapper = new LambdaQueryWrapper<>();
        if (model.getAccount().isEmpty() || model.getPassword().isEmpty()) {
            log.warn("登录参数校验失败：用户名或密码为空，账号：{}", account);
            return Result.error(400, "用户名或密码不能为空");
        }
        try {
            if (StringUtilsKt.isPhoneNumber(account)) {
                wrapper.eq(AccountModel::getPhone, account);
                log.debug("登录方式：手机号登录，查询条件：phone={}", account);
            } else {
                wrapper.eq(AccountModel::getUsername, account);
                log.debug("登录方式：用户名登录，查询条件：username={}", account);
            }
            AccountModel userAuthInfo = authMapper.selectOne(wrapper);
            log.debug("数据库查询结果：用户是否存在={}", userAuthInfo != null);
            if (userAuthInfo == null) {
                log.warn("登录失败：用户不存在，账号：{}", account);
                return Result.error(404, "用户不存在,请先注册");
            }
            String rawPassword = model.getPassword();
            String encryptedPassword = userAuthInfo.getPassword();
            boolean passwordMatch = bCryptPasswordEncoder.matches(rawPassword, encryptedPassword);
            log.debug("密码校验结果：{}，用户ID：{}", passwordMatch, userAuthInfo.getId());
            if (passwordMatch) {
                LoginResultModel loginResultModel = new LoginResultModel();
                loginResultModel.setToken(JWTUtils.getToken(userAuthInfo));
                loginResultModel.setUserId(userAuthInfo.getId());
                loginResultModel.setTokenExpireTime(JWTUtils.getExpiration());
                log.info("登录成功：用户ID={}，账号={}，令牌过期时间={}", userAuthInfo.getId(), account, loginResultModel.getTokenExpireTime());
                return Result.success("登录成功", loginResultModel);
            }
            log.warn("登录失败：账号或密码错误，账号：{}", account);
            return Result.error(401, "账号或密码错误");
        } catch (Exception e) {
            log.error("登录系统异常：账号={}，异常信息={}", account, e.getMessage(), e);
            return Result.error(500, "系统异常，请稍后再试");
        }
    }

    @Override
    public Result registerService(AuthModel model) {
        log.info("开始处理注册请求，账号：{}，密码：{}", model.getAccount(), model.getPassword().isBlank() ? "空" : "******");

        String account = model.getAccount();
        String password = model.getPassword();

        AccountModel userAuthInfo = new AccountModel();
        LambdaQueryWrapper<AccountModel> wrapper = new LambdaQueryWrapper<>();
        if (account.isEmpty() || password.isEmpty()) {
            log.warn("注册参数校验失败：账号或密码为空，账号：{}", account);
            return Result.error(400, "账号和密码不能为空");
        }
        boolean isPhoneNumber = StringUtilsKt.isPhoneNumber(account);
        if (isPhoneNumber) {
            wrapper.eq(AccountModel::getPhone, account);
            userAuthInfo.setUsername(StringUtils.randomUsername(8, true, true));
            userAuthInfo.setPhone(account);
            log.debug("注册方式：手机号注册，查询条件：phone={}", account);
        } else {
            wrapper.eq(AccountModel::getUsername, account);
            userAuthInfo.setUsername(account);
            log.debug("注册方式：用户名注册，查询条件：username={}", account);
        }
        long count = authMapper.selectCount(wrapper);
        log.debug("账号唯一性校验结果：已存在数量={}，账号：{}", count, account);
        if (count > 0) {
            String msg = isPhoneNumber ? "手机号已被占用，请更换其他手机号" : "用户名已被占用，请更换其他用户名";
            log.warn("注册失败：{}，账号：{}", msg, account);
            return Result.error(400, msg);
        }

        String rawPassword = model.getPassword();
        String encryptedPassword = bCryptPasswordEncoder.encode(rawPassword);
        userAuthInfo.setPassword(encryptedPassword);
        log.debug("注册密码加密完成：账号={},加密后密码长度：{}", account, encryptedPassword.length());
        userAuthInfo.setIsVip(0);
        try {
            int rows = authMapper.insert(userAuthInfo);
            log.debug("数据库插入结果：受影响行数={}，账号={}", rows, account);
            if (rows > 0) {
                log.info("注册成功：账号={}，用户名={}，用户ID={}", account, userAuthInfo.getUsername(), userAuthInfo.getId());
                return Result.success("注册成功", null);
            } else {
                log.warn("注册失败：数据库插入无影响行数，账号：{}", account);
                return Result.error(401, "注册失败，请重试");
            }
        } catch (DuplicateKeyException e) {
            String msg = isPhoneNumber ? "手机号已被占用，请更换其他手机号" : "用户名已被占用，请更换其他用户名";
            log.error("注册失败：{}（唯一键冲突），账号：{}，异常信息={}", msg, account, e.getMessage());
            return Result.error(400, msg);
        } catch (Exception e) {
            log.error("注册系统异常：账号={}，异常信息={}", account, e.getMessage(), e);
            return Result.error(500, "系统异常，请稍后再试");
        }
    }
}
